home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gigarom 1
/
Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso
/
FILES
/
DEV
/
I-Z
/
Long Labels User Area.cpt
/
Long Labels User Area
/
Label.a
next >
Wrap
Text File
|
1989-03-10
|
19KB
|
624 lines
;This label.a file works with some of the new long label
;formats generated by MPW 3.0. This is useful so you can
;find long labels in your code from TMON. Since long labels
;didn't exist when TMON was originally written, proper
;long label support is only available in TMON Professional.
;
;Modified 12/7/88 to work with both old and new labels
;(as was originally intended for this version).
;
;Modified 3/10/89 by Paul F. Snively to correctly support
;MPW 3.0 frozen release long labels as well as "old-style
;MacsBug" eight-character labels.
INCLUDE 'Labels.a'
CodeResources
;Resources which may contain code.
DC.L ('CODE')
DC.L ('CACH') ;File system cache.
DC.L ('CDEF') ;Control defProc.
DC.L ('cdev') ;Control device.
DC.L ('DRVR') ;Driver.
DC.L ('DSAT') ;DS Alert code.
DC.L ('FKEY') ;Shift-Cmd code.
DC.L ('FMTR') ;Formatting code.
DC.L ('INIT') ;Initialization.
DC.L ('LDEF') ;List defProc.
DC.L ('MBDF') ;Menu Bar defProc.
DC.L ('MDEF') ;Menu defProc.
DC.L ('NBPC') ;Name-binding protocol (AppleTalk).
DC.L ('PACK') ;Package.
DC.L ('PDEF') ;Printing defProc.
DC.L ('PROC') ;Generic code.
DC.L ('PATC') ;Patches.
DC.L ('PTCH') ;Patches.
DC.L ('SERD') ;RAM serial driver.
DC.L ('WDEF') ;Window defProc.
DC.L ('XCMD') ;Hypercard external command.
DC.L ('XFCN') ;Hypercard external function.
DC.L ('tcod') ;Apple File Exchange.
DC.L ('tprc') ;Apple File Exchange.
DC.L ('4NFS') ;Apple File Exchange.
DC.L ('MCMC') ;Apple File Exchange.
DC.L ('MCPD') ;Apple File Exchange.
DC.L ('MCMS') ;Apple File Exchange.
DC.L ('PDMC') ;Apple File Exchange.
DC.L ('PDPD') ;Apple File Exchange.
DC.L ('PDMS') ;Apple File Exchange.
DC.L ('MSMC') ;Apple File Exchange.
DC.L ('MSPD') ;Apple File Exchange.
DC.L ('MSMS') ;Apple File Exchange.
;This is a patch area primarily for those who do not have MPW and need
;to patch this list instead of changing the source and rebuilding. If
;you want to add new resource types to this list, you can add them
;after the last valid type, replacing longwords of zero. There must
;be one zero terminator (longword) to end this list.
DC.L 0
DC.L 0
DC.L 0
DC.L 0
DC.L 0
DC.L 0
;######################
;## ##
;## Label routines ##
;## ##
;######################
;+--------------------------------------------------------+
;| Check if D2 is in a code resource, and, if it is, |
;| attempt to find the name of the routine containing D2. |
;+--------------------------------------------------------+
;|
;|ENTRY: CodeLabelScan
;|
;|IN: D2.L: address to identify.
;| D0.L: 0.
;| D5.L: if D2 is in a resource, offset from the resource beginning to D2.
;| D6.L: if D2 is in a resource, the resource type; otherwise, 0.
;| D7.L: Bits 0..15 contain the resource ID. Bits 16..23 contain the value of _Inhibits.
;| A4: if D2 is in a resource, beginning address of the heap block. (D2:-D5:)
;| A3: if D2 is in a resource, ending address of the heap block. (D2:-D5:)
;| A5: ^Monitor's variables.
;|(D4 is initialized by the Monitor, but this routine does not use it.)
;|
;|OUT: D0.L'=0 D2 could not be identified.
;| D2.L' D2.L:.
;| D0.L'<>0 D2 was identified.
;| D0.L' first four letters of name.
;| D1.L' last four letters of name.
;| A1' address of the routine's beginning (the LINK instruction).
;| D2.L' D2.L:-A1'.
;|
;|Destroys D1,D3,A0,A1.
;|
CodeLabelScan
MOVEM.L D4/D5/D6/D7,-(SP) ;Save registers.
LEA CodeResources,A0
CheckCodeTypes
MOVE.L (A0)+,D1 ;Check next type.
BEQ.S NoCodeLabel
CMP.L D1,D6 ;Don't search for code routine names unless this is
BNE.S CheckCodeTypes ;a code segment.
MOVE.L D2,D7 ;D7 will contain D2 truncated to an even value.
BCLR #0,D7
MOVE.L D7,A0
MOVE.L A3,D3 ;D3 contains the number of words left to scan
SUB.L D7,D3 ;before giving up at $800 or finishing at the end of
CMP.W #$800,D3 ;the block.
BCS.S @1
MOVE.W #$800,D3
@1 LSR.W #1,D3
ADDQ.L #2,D7 ;Increment the starting position pointer by 2.
ExamineCode MOVE.W #$4E75,D1 ;D1.W: RTS
MOVE.W #$4ED0,D6 ;D6.W: JMP (A0)
MOVE.W LINKAx,D4 ;D4.W: LINK A6,#____
BRA.S SearchNextCodeLabel
LoopNextCodeLabel
MOVE.W (A0)+,D0 ;Get the next word.
CMP.W D1,D0 ;Search for one of the above instructions.
BEQ.S InvestigateLabel ;If RTS or JMP (A0) is found, investigate further.
CMP.W D6,D0
BEQ.S InvestigateLabel
CMP.W D4,D0
SearchNextCodeLabel
DBEQ D3,LoopNextCodeLabel ;If the LINK is found first, exit with no label.
BNE.S NoCodeLabel ;If the LINK is the first instruction encountered,
CMPA.L D7,A0 ;leave it as it is because it may be the beginning
BEQ.S ExamineCode ;of the subroutine.
NoCodeLabel
MOVEQ #0,D0 ;Pass back no label code.
DoneCodeLabel
MOVEM.L (SP)+,D4/D5/D6/D7 ;Return.
RTS
InvestigateLabel
CMP.W #4,D3 ;If there are less than eight bytes left to scan,
BCS.S NoCodeLabel ;it's not possible to have a full name here.
BSR.S CheckUNLK ;Check for an UNLK instruction before the RTS or
BNE.S SearchNextCodeLabel ;JMP (A0). If not found, continue searching.
MOVE.B (A0),D6
CMP.B #$81,D6
BCS.S CheckVeryLong
CMP.B #$A0,D6
BCC.S CheckTheLetters
ADDA.L #1,A0
AND.B #$7F,D6
CMP.B #8,D6
BCS.S @1
MOVEQ #8,D6
@1 MOVE.L A1,-(A7)
MOVE.L #' ',-(A7)
MOVE.L #' ',-(A7)
MOVE.L A7,A1
@2 MOVE.B (A0)+,(A1)+
SUBQ.B #1,D6
BNE.S @2
MOVEM.L (A7)+,D0/D1/A1
BRA.S FoundTheLetters
CheckVeryLong CMP.B #$80,D6
BNE.S CheckTheLetters
ADDA.L #2,A0
CheckTheLetters MOVEQ #7,D6
Check8Letters
ROL.L #8,D0 ;Check the name to make sure that there are eight
ROL.L #8,D1 ;letters of valid ASCII values present.
MOVE.B D1,D0
MOVE.B (A0)+,D1
CMP.B #6,D6
BCS.S @1
AND.B #$7F,D1 ;Clear the high bit of the first and second bytes.
@1 CMP.B #' ',D1 ;Anything between $20 and $7E is valid.
BCS.S NoCodeLabel
CMP.B #$7F,D1
BCC.S NoCodeLabel
DBRA D6,Check8Letters
FoundTheLetters MOVE.L D5,D3 ;A valid name has been found. Now search backwards
LSR.L #1,D3 ;for the LINK instruction.
MOVE.L D7,A1
@2 CMP.W -(A1),D4
DBEQ D3,@2
BNE.S NoCodeLabel ;If run out of the block, exit.
SUB.L A1,D2 ;Otherwise give the offset in D2 and return
BRA.S DoneCodeLabel ;successfully.
;+-------------------------------------------------------+
;| Make sure that an UNLK A6 instruction exists no more |
;| than ten words in front of A0. Also make sure that |
;| there is no LINK A6 between the UNLK A6 and A0. |
;+-------------------------------------------------------+
;|
;|ENTRY: CheckUNLK
;|
;|IN: A0: Address from which to search.
;|
;|OUT: Z flag' set if the conditions above satisfied, clear otherwise.
;|
;|Destroys nothing.
;|
CheckUNLK MOVEM.L D0-D2/A0,-(SP) ;Save registers.
MOVEQ #9,D0 ;Search ten words.
MOVE.W UNLKAx,D1
MOVE.W LINKAx,D2
@1 CMP.W -(A0),D1 ;UNLK A6
BEQ.S @2
CMP.W (A0),D2 ;LINK A6,#____
DBEQ D0,@1
MOVEQ #-1,D0 ;If not found or LINK found first, clear Z flag.
@2 MOVEM.L (SP)+,D0-D2/A0 ;Return (MOVEM preserves flags).
RTS
;+----------------------------------+
;| Find a given embedded routine |
;| 8-character name in code blocks. |
;| See manual for details. |
;+----------------------------------+
;|
;|ENTRY: CodeLabelFind
;|
;|IN: D0.L: first four characters of the name converted to upper case.
;| D1.L: last four characters of the name converted to upper case.
;| D7.L: bits 16..23 contain the value of _Inhibits.
;| A5: ^Monitor's variables.
;|
;|OUT: D0.L'=0 the name has been found.
;| D2.L' the location of the routine that has the given name.
;| D0.L'=D0.L: the name has not been found.
;|
;|Destroys D2,D3,A0,A1.
;|
CodeLabelFind
MOVEM.L D0/D1/D4-D7/A2-A4/A6,-(SP)
BTST #16+3,D7 ;If can't scan resources, do nothing.
BNE DoneCodeLabelFind
MOVE.L SP,A6
MOVE.L TopMapHndl,D1 ;Start with the first resource file.
NextResourceFile
JSR _NextCResFile ;Check the next file.
BEQ DoneCodeLabelFind ;If there is none, no data will be found.
MOVE.L A1,A3
MOVE.W (A3)+,D6 ;D6 has the number of types+1.
BMI.S NextResourceFile
DoNextResourceType
MOVE.L (A3)+,D2 ;Get the resource type.
ADDQ.W #4,A3 ;Look for blocks of type proper type.
LEA CodeResources,A4
CheckCodeResourceTypes
MOVE.L (A4)+,D0 ;Check next type.
BEQ.S NotACodeResourceType
CMP.L D0,D2 ;Don't search for code routine names unless this is
BEQ.S IsACodeResourceType ;a code segment.
BRA.S CheckCodeResourceTypes
NotACodeResourceType
MOVEQ #-1,D0
IsACodeResourceType
DBEQ D6,DoNextResourceType ;Check the next resource type.
BNE.S NextResourceFile ;If not found, scan the next file.
SWAP D6 ;Put the count away in the high word.
MOVE.W -2(A3),D0
LEA 0(A1,D0.W),A2 ;Find the ID list and check for address errors.
LSR.B #1,D0
BCS.S NextResourceFile
MOVE.W -4(A3),D6 ;D6 now has the number of IDs in the table.
BMI.S NextResourceType
DoNextResource
ADDQ.W #8,A2
MOVE.L (A2)+,A0 ;See if this resource is legally in memory.
BSR IndirectA0
BCS.S NextResource ;NO.
MOVE.L -8(A0),D0
StripAddress D0
MOVEQ #$0F,D2
AND.B -8(A0),D2 ;Subtract the size correction from the size.
SUB.L D2,D0
MOVEQ #8,D2
SUB.L D2,D0
BMI.S NextResource ;If a negative number results, skip to the
LSR.L #1,D0 ;next block.
CMP.L #$8000,D0
BLO.S @1
MOVE.L #$7FFF,D0
@1
MOVE.W LINKAx,D2 ;D2.W: LINK A6,#____
MOVE.W #$4E75,D3 ;D3.W: RTS
MOVE.W #$4ED0,D4 ;D4.W: JMP (A0)
BRA.S FindLink
DoFindLink
CMP.W (A0)+,D2 ;Search for a LINK instruction.
FindLink
DBEQ D0,DoFindLink
BNE.S NextResource ;Not found within the block.
FindReturnUnlink
MOVE.L A0,D7 ;Anchor the address and look for
MOVEQ #-1,D5 ;Always set the flag to NE.
BRA.S FindReturn ;an RTS or JMP (A0).
DoFindReturn
MOVE.W (A0)+,D5
CMP.W D5,D3
BEQ.S CheckUnlink
CMP.W D5,D4
BEQ.S CheckUnlink
CMP.W D5,D2 ;If another LINK is found first, restart this loop.
FindReturn
DBEQ D0,DoFindReturn
BNE.S NextResource
BRA.S FindReturnUnlink ;Search again.
CheckUnlink
BSR CheckUNLK ;Check for an UNLK instruction before the RTS or
BNE.S FindReturn ;JMP (A0).
BSR.S CheckName
BNE.S FindLink
FoundCodeLabel
SUBQ.L #2,D7 ;Return the code label in D2.
MOVE.L D7,D2
CLR.L (SP) ;Clear D0 on the stack image.
DoneCodeLabelFind
MOVEM.L (SP)+,D0/D1/D4-D7/A2-A4/A6
RTS
NextResource
DBRA D6,DoNextResource ;Examine the next block, or, if there are no more,
NextResourceType
SWAP D6 ;Bring the count back from the high word.
BRA DoNextResourceType
;+---------------------------------------------------------------------------------+
;| Compare the names at (A0)+ and (A6)+. Convert the name at (A0)+ to upper case |
;| and clear the 7th bit in its first 2 characters for the purpose of comparison. |
;| The name at (A6)+ is assumed to be in upper case, as it will be if it was |
;| generated by the Monitor. Both names must be eight characters long. |
;+---------------------------------------------------------------------------------+
;|
;|ENTRY: CheckName
;|
;|IN: A0: string1, upper or lower case, 7th bit clear or set on first character.
;| A6: string2, upper case only, 7th bit clear.
;|
;|OUT: Z flag' set if uppercase(string1)=string2
;| clear otherwise.
;|
;|Destroys nothing.
;|
CheckName: MOVEM.L D0/D1/A1/A2,-(SP)
MOVEQ #0,D0
MOVE.B (A0),D0
CMP.B #$81,D0
BCS.S OldCheckName
CMP.B #$C0,D0
BCC.S OldCheckName
SUB.B #$80,D0
CMP.B #8,D0
BCS.S @1
MOVEQ #8,D0
BRA.S @2
@1 CMP.B #' ',0(A6,D0.W)
BNE.S BadCheckName
@2 SUBQ.B #1,D0
MOVE.L A0,A2
ADDQ.W #1,A2
BRA.S OldCheckName2
OldCheckName: MOVEQ #7,D0 ;Compare eight characters.
MOVE.L A0,A2
OldCheckName2: MOVE.L A6,A1 ;Use copies of A0 and A6.
@4 MOVEQ #$7F,D1 ;Clear the high bit of the first character.
AND.B (A2)+,D1
BRA.S @3
@1 CMP.B #6,D0
BHS.S @4
MOVE.B (A2)+,D1
@3 CMP.B #'a',D1 ;Convert to upper case.
BCS.S @2
CMP.B #'z'+1,D1
BCC.S @2
SUB.B #$20,D1
@2 CMP.B (A1)+,D1 ;Compare and exit as soon as a mismatch is found or
DBNE D0,@1 ;eight characters match.
BadCheckName: MOVEM.L (SP)+,D0/D1/A1/A2
RTS
;+---------------------------+
;| Find a given 8-character |
;| label in the label table. |
;| See manual for details. |
;+---------------------------+
;|
;|ENTRY: LabelFind
;|
;|IN: D0.L: first four characters of the name converted to upper case.
;| D1.L: last four characters of the name converted to upper case.
;| D7: bits 16..23 contain the value of _Inhibits.
;| A5: ^Monitor's variables.
;|
;|OUT: D0.L'=0 the name has been found.
;| D2.L' the location of the routine that has the given name.
;| D0.L'=D0.L: the name has not been found.
;| D2.L' unpredictable.
;|
;|Destroys D3,A0,A1.
;|
;|
;|ENTRY: LabelFind.
;|
;|Same as LabelFind except that if D2.B is nonzero, the subroutine will not check if the resource is in
;|memory for resource-relative labels. Moreover, the address of the label will be passed back in
;|A0 if the label is found. However the address of built-in labels is never returned.
;|
LabelFind: MOVEQ #0,D2
LabelFind_:
MOVE.B LabelEnabled,D3 ;If there is no table of labels, do nothing.
MOVEM.L D0/D1/D5/D6/A3/A4/A6,-(SP)
MOVE.L SP,A6 ;A6 points to the saved name on the stack.
BMI.S @20
MOVE.L LabelTable,A0
SUBQ.W #8,A0
MOVE.W NumLabels,D3
MOVEQ #-1,D0 ;Clear the Z flag.
BRA.S @2
@1 ADD.W #16,A0 ;Check the names in the label table.
BSR CheckName
@2 DBEQ D3,@1
BEQ.S @21 ;If found, continue
@20 MOVE.L UALabelTable,A0 ;Point to built in label table.
SUBQ.L #8,A0
MOVE.W NumUALabels,D3
MOVEQ #-1,D0
BRA.S @22
@23 ADD.W #16,A0
BSR CheckName
@22 DBEQ D3,@23
@21 BNE.S @10 ;If no match, exit.
MOVE.L -(A0),D3 ;Determine whether this is an absolute or
MOVE.B D2,D0 ;resource-relative label.
MOVE.L -(A0),D2
TST.B (A0)
BEQ.S @3 ;If absolute, exit successfully.
TST.B D0
BNE.S @3 ;If supposed to pass back label address, exit now.
BTST #16+3,D7 ;If resource-relative, resource scanning must not be
BNE.S @10 ;inhibited!
SWAP D3
JSR _FindRes ;Find the desired resource, and, if all is well,
TST.B D0 ;add the offset to its beginning.
BNE.S @10
CLR.W D3
SWAP D3
ADD.L D3,D2
@3
MOVE.L UALabelTable,A1
CMP.L A1,A0
BLO.S @24
MOVE.L UALabelTableEnd,A1
CMP.L A1,A0
BHS.S @24
MOVEQ #0,D0
MOVE.L D0,A0 ;Do NOT return a pointer for built-ins
@24 CLR.L (SP) ;Clear D0 on the stack image.
@10 MOVEM.L (SP)+,D0/D1/D5/D6/A3/A4/A6
@11 RTS
;+------------------------------------+
;| Search the label table for a label |
;| that could be used to identify D2. |
;| The resource-relative labels will |
;| be ignored if D6 is 0. |
;+------------------------------------+
;|
;|ENTRY: LabelScan
;|
;|IN: D2.L: address to identify.
;| D0.L: 0.
;| D5.L: if D2 is in a resource, offset from the resource beginning to D2.
;| D6.L: if D2 is in a resource, the resource type; otherwise, 0.
;| D7.L: Bits 0..15 contain the resource ID. Bits 16..23 contain the value of _Inhibits.
;| A4: if D2 is in a resource, beginning address of the heap block. (D2:-D5:)
;| A3: if D2 is in a resource, ending address of the heap block. (D2:-D5:)
;| A5: ^Monitor's variables.
;|(D4 is initialized by the Monitor, but this routine does not use it.)
;|
;|OUT: D0.L'=0 D2 could not be identified.
;| D2.L' D2.L:.
;| D0.L'<>0 D2 was identified.
;| D0.L' first four letters of name.
;| D1.L' last four letters of name.
;| D2.L' offset from the label to D2.L.
;|
;|Destroys D1,D3,A0,A1.
;|
LabelScan: CMP.L OSTableStart,D2 ;Are we in the OS trap table?
BLO.S @1
CMP.L OSTableEnd,D2 ;Are we past the end of the trap table?
BLO.S OSTableScan
@1
CMP.L ToolTableStart,D2 ;Are we in the Tool trap table?
BLO.S LabelTableScan
CMP.L ToolTableEnd,D2 ;Are we past the end of the trap table?
BLO.S ToolTableScan
LabelTableScan
MOVEM.L D4/D5,-(SP) ;Save registers.
MOVEQ #-1,D5 ;Assume that the best fit was 4294967295 bytes off.
MOVE.B LabelEnabled,D3 ;If there is no table of labels, do nothing.
BMI.S @20
MOVE.L LabelTable,A0
MOVE.W NumLabels,D3
BRA.S @10
@1 MOVE.L A0,A1 ;Which type of a label is this?
TST.B (A1)
BEQ.S @2
CMP.L (A1)+,D6 ;Resource-type. The resource type and ID must
BNE.S @5 ;match exactly.
CMP.W (A1)+,D7
BNE.S @5
MOVEQ #0,D4 ;Get the address pointed by this label into D4.
MOVE.W (A1)+,D4
ADD.L A4,D4
BRA.S @3
@2 MOVE.L (A1)+,D4 ;Absolute-type. The given location must be below
CMP.L (A1)+,D2 ;the maximum address given. If it is, get the
BCC.S @5 ;address pointed by this label into D4.
@3 SUB.L D4,D2
BCS.S @4 ;Calculate the difference between D4 and the
CMP.L D5,D2 ;location given, and check if this is a closest
BCC.S @4 ;match.
MOVE.L D2,D5
MOVE.L (A1)+,D0 ;If so, copy the name into D0 and D1 and the
MOVE.L (A1),D1 ;difference into D5.
@4 ADD.L D4,D2
@5 ADD.W #16,A0
@10 DBRA D3,@1
MOVE.L UALabelTableEnd,A1 ;Check if we were scanning the built in table.
CMP.L A0,A1
BEQ.S @21 ;If so, we are done
@20 MOVE.L UALabelTable,A0
MOVE.W NumUALabels,D3
BRA.S @10
@21 TST.L D0 ;If a good label has been found, put the difference
BEQ.S @11 ;into D2.
MOVE.L D5,D2
@11 MOVEM.L (SP)+,D4/D5 ;Restore registers.
@12 RTS
OSTableScan
MOVE.L OSTableStart,D1
MOVE.W #$A000,D3 ;Set up for an OS trap.
BRA.S TrapTableScan
ToolTableScan
MOVE.L ToolTableStart,D1
MOVE.W #$A800,D3 ;Set up for a tool trap.
TrapTableScan
MOVE.W D2,D0 ;Calculate a trap number.
SUB.W D1,D0 ;An offset into the trap table.
MOVE.W D0,-(SP)
LSR.W #2,D0 ;A trap number.
OR.W D3,D0 ;A trap.
LEA TrapNameBuffer+8,A0 ;A place to disassemble.
MOVE.L #' ',D1
MOVE.L D1,-(A0)
MOVE.L D1,-(A0)
BSR.S DisA000Y
LEA TrapNameBuffer,A0 ;Point to buffer again.
CMP.B #'_',(A0)
BEQ.S @2
LEA TrapNameBuffer+7,A1
MOVEQ #6,D1
@1 MOVE.B -(A1),1(A1)
DBRA D1,@1
@2 MOVEM.W (SP)+,D2 ;Get the offset in D2.
MOVE.B #'j',(A0) ;Replace the underline with a j.
MOVE.L (A0)+,D0
MOVE.L (A0),D1
AND.L #3,D2 ;Make that offset.
RTS
TrapNameBuffer DCB.B 20,0 ;A buffer for trap names.
;+----------------------------------------------------+
;| This subroutine disassembles a single A000 trap. |
;| The string has one of two formats: |
;| _name if the trap could be recognized to be name, |
;| $Annn if the trap could not be recognized. |
;+----------------------------------------------------+
;|
;|ENTRY: DisA000Y
;|
;|IN: D0: A000 trap to be disassembled (only the low 12 bits are significant).
;| A0: ^the text record for the instruction.
;|
;|OUT: A0' 1+^the last character of the string.
;|
;|Destroys A0-A1,D0-D2.
;|
DisA000Y: MOVEM.L D3/D4/A2,-(A7)
MOVE.L A0,A2
MOVE.W D0,D2
MOVEQ #-1,D0 ;Don't include the hexadecimal digit
JSR _CallDisA000 ;indicator after the trap name.
MOVEA.L A2,A0
MOVEM.L (A7)+,D3/D4/A2
RTS